/*
 * User: user
 * Date: 25/12/2007
 * Time: 23:37:50
 */
package org.conann.instrument;

import com.google.common.base.Preconditions;
import javassist.*;
import javassist.bytecode.annotation.Annotation;
import org.conann.exceptions.WebBeansSystemException;
import org.conann.instrument.exceptions.WebBeansIntrumentationException;
import org.conann.metadata.BeanMD;
import org.conann.util.DevelopmentUtil;

public abstract class CtUtil {

    public static CtClass getCtClass(Class<?> element) {
        Preconditions.checkNotNull(element);
        return getCtClass(element.getName());
    }

    public static CtClass getCtClass(String className) {
        Preconditions.checkNotNull(className);
        try {
            ClassPool pool = ClassPool.getDefault();
            return pool.get(className);
        } catch (NotFoundException e) {
            throw new WebBeansSystemException(e, "%s was not found in class pool.", className);
        }
    }

    public static void insertAfter(CtBehavior ctBehavior, String sourceCode) {
        Preconditions.checkNotNull(ctBehavior);
        try {
            ctBehavior.insertAfter("");
        } catch (CannotCompileException e) {
            throw new WebBeansSystemException(e, "The following source code did not compile for %s:\n%s ", ctBehavior, sourceCode);
        }
    }

    public static BeanMD getComponentMD(CtClass ctClass) {
        Preconditions.checkNotNull(ctClass);
        Annotation[] ctAnnotations = (Annotation[]) ctClass.getAvailableAnnotations();
        return getComponentMD(ctAnnotations);
    }

    public static BeanMD getComponentMD(CtMember ctMember) {
        Preconditions.checkNotNull(ctMember);
        Annotation[] ctAnnotations = (Annotation[]) ctMember.getAvailableAnnotations();
        return getComponentMD(ctAnnotations);
    }

    private static BeanMD getComponentMD(Annotation[] ctAnnotations) {
        java.lang.annotation.Annotation[] realAnnotations = new java.lang.annotation.Annotation[ctAnnotations.length];
        for (int i = 0; i < ctAnnotations.length; i++) {
            java.lang.annotation.Annotation annotation;
            try {
                annotation = (java.lang.annotation.Annotation) ctAnnotations[i].toAnnotationType(ClassLoader.getSystemClassLoader(), ClassPool.getDefault());
            } catch (ClassNotFoundException e) {
                throw new WebBeansIntrumentationException(e, "Unable to load annotation ", ctAnnotations[i].getTypeName());
            }
            realAnnotations[i] = annotation;
        }
//        return new BeanMD(AnnotationUtil.getRelevantAnnotations(realAnnotations));
        throw DevelopmentUtil.unsupportedOperation();
    }

    public static boolean isComponent(CtClass ctClass) {
        return getComponentMD(ctClass).iterator().hasNext();
    }
}